package io.nanfeng.webflux

import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.reactor.awaitSingleOrNull
import org.springframework.http.server.reactive.ServerHttpRequest
import org.springframework.stereotype.Component
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.server.WebFilter
import org.springframework.web.server.WebFilterChain
import reactor.core.publisher.Mono
import reactor.util.context.Context

@Component
class RequestHolderWebFilter : WebFilter {
    override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
        val request = exchange.request
        return chain.filter(exchange)
            .contextWrite(Context.of(ServerHttpRequest::class.java, request))
    }
}

object RequestContextHolder


    fun RequestContextHolder.currenRequest(): Mono<ServerHttpRequest?> {
        return Mono.deferContextual {
            Mono.just(it.get(ServerHttpRequest::class.java))
        }
    }

    @RestController
    class TestController {

        @GetMapping("/test")
        fun test(): Mono<String>? {
            return RequestContextHolder.currenRequest()
                .mapNotNull { it?.uri?.toString() }
        }

        @GetMapping("/test1")
        suspend fun test1(): String?{
            return RequestContextHolder.currenRequest()
                .awaitSingleOrNull()?.uri?.toString()
        }

    }


